package com.fruit.service.sms.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.fruit.mapper.sms.SmsCodeMapper;
import com.fruit.pojo.sms.NoticeSms;
import com.fruit.pojo.sms.SmsCodeValidate;
import com.fruit.pojo.sms.SmsTemplet;
import com.fruit.pojo.user.UserLogin;
import com.fruit.service.sms.SmsCodeManager;
import com.fruit.service.user.UserManager;
import com.fruit.util.CustomUtil;
import com.fruit.util.DateUtil;
import com.fruit.util.ResultInfo;
import com.fruit.util.ResultUtil;
import com.fruit.util.sms.code.NeteaseSms;

import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;

@Service
@Slf4j
public class SmsCodeService implements SmsCodeManager {
	protected Logger logger = LoggerFactory.getLogger(SmsCodeService.class);

	@Autowired
	private SmsCodeMapper smsCodeMapper;

	@Autowired
	private UserManager userService;

	public String sendSmsCode(String type, String code, String phone) {
		SmsTemplet st = smsCodeMapper.getSmsTempletByCode(type);
		String result = null;
		if (st != null) {
			st.setUrl(st.getSendUrl());
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			// 模板id
			nvps.add(new BasicNameValuePair("templateid", st.getTempletId()));
			// 参数jsonArray形式
			nvps.add(new BasicNameValuePair("mobiles", "['" + phone + "']"));
			nvps.add(new BasicNameValuePair("params", "['" + code + "']"));

			result = NeteaseSms.newPost(st, nvps);
		}

		return result;
	}

	@Override
	public Map<String, Object> sendNoticeSmsToDB(String type, String phone) {
		log.warn("通知短信---开始发送");
		Map<String, Object> resMap = new HashMap<String, Object>();
		if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(type)) {
			resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "no-param", "缺少参数"));
			return resMap;
		}
		String msg = "";
		try {
			NoticeSms ns = new NoticeSms();
			ns.setPhone(phone);
			ns.setType(type);
			ns.setCreateTime(DateUtil.getTime());
			int num = smsCodeMapper.saveNoticeSms(ns);
			if (num > 0) {
				msg = sendNoticeSms(type, "", phone);
			} else {
				log.warn("通知短信---发送失败");
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "ERROR", "发送失败"));
				return resMap;
			}
			resMap.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "success", "发送成功"));
			log.warn("通知短信---发送成功");
		} catch (Exception e) {
			e.printStackTrace();
			log.warn("通知短信---发送异常");
		} finally {
			if (!"success".equals(msg)) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}
		}
		return resMap;
	}

	@Override
	public Map<String, Object> sendBonusToDB(String type, Integer userId, String params) {
		log.warn("通知短信---开始发送");
		Map<String, Object> resMap = new HashMap<String, Object>();
		if (userId == null || StringUtils.isEmpty(type) || StringUtils.isEmpty(params)) {
			resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "no-param", "缺少参数"));
			return resMap;
		}
		String msg = "";
		try {
			String phone = smsCodeMapper.getLoginPhone(userId);
			log.warn("通知短信---[手机号]------" + phone);
			NoticeSms ns = new NoticeSms();
			ns.setPhone(phone);
			ns.setType(type);
			if (!StringUtils.isEmpty(params)) {
				ns.setMessage(params);
			}
			ns.setCreateTime(DateUtil.getTime());
			int num = smsCodeMapper.saveNoticeSms(ns);
			if (num > 0) {
				msg = sendNoticeSms(type, params, phone);
			} else {
				log.warn("通知短信---发送失败");
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "ERROR", "发送失败"));
				return resMap;
			}
			resMap.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "success", "发送成功"));
			log.warn("通知短信---发送成功");
		} catch (Exception e) {
			e.printStackTrace();
			log.warn("通知短信---发送异常");
		} finally {
			if (!"success".equals(msg)) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}
		}
		return resMap;
	}

	public String sendNoticeSms(String type, String params, String phone) {
		logger.info("发送短信---【开始】---" + phone + "----" + params);
		String result = "";
		try {
			SmsTemplet st = smsCodeMapper.getSmsTempletByCode(type);
			logger.info("发送短信---【type类型查询】----" + st);
			if (st != null) {
				SendSmsRequest request = new SendSmsRequest();
				JSONObject jsonCode = new JSONObject();
				if (!StringUtils.isEmpty(params)) {
					request.setTemplateParam(jsonCode.toString());
					String[] pa = params.split(",");
					jsonCode.accumulate("time", pa[0]);
					jsonCode.accumulate("money", pa[1]);
					request.setTemplateParam(jsonCode.toString());
				}
				request.setPhoneNumbers(phone);
				request.setAcceptFormat(FormatType.JSON);
				result = sendCode(request, st);
				logger.info("发送短信---【返回值】----" + result);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public String sendCode(String type, String params, String phone) {
		logger.info("发送短信---【开始】---" + phone + "----" + params);
		String result = "";
		try {
			SmsTemplet st = smsCodeMapper.getSmsTempletByCode(type);
			logger.info("发送短信---【type类型查询】----" + st);
			if (st != null) {
				SendSmsRequest request = new SendSmsRequest();
				JSONObject jsonCode = new JSONObject();
				if (!StringUtils.isEmpty(params)) {
					jsonCode.accumulate("code", params);
					request.setTemplateParam(jsonCode.toString());
				}
				request.setPhoneNumbers(phone);
				request.setAcceptFormat(FormatType.JSON);
				result = sendCode(request, st);
				logger.info("发送短信---【返回值】----" + result);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public String sendCode(SendSmsRequest request, SmsTemplet st) {
		SendSmsResponse sendSmsResponse = null;
		String result = "";
		try {
			IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", st.getAppKey(), st.getAppSecret());
			DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", "Dysmsapi", st.getSendUrl());
			IAcsClient acsClient = new DefaultAcsClient(profile);
			request.setMethod(MethodType.POST);
			request.setSignName(st.getSign());
			request.setTemplateCode(st.getTempletId());
			sendSmsResponse = acsClient.getAcsResponse(request);
			if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
				result = "success";
			} else {
				result = "error1";
			}
		} catch (ClientException e) {
			e.printStackTrace();
			logger.info("发送短信---【异常】---" + e.getMessage());
			result = "error";
		}
		return result;
	}

	public String sendSmsNotice(String type, String phones, String params) {
		SmsTemplet st = smsCodeMapper.getSmsTempletByCode(type);
		String result = null;
		if (st != null) {
			st.setUrl(st.getSendUrl());
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			// 模板id
			nvps.add(new BasicNameValuePair("templateid", st.getTempletId()));
			// 参数jsonArray形式
			nvps.add(new BasicNameValuePair("mobiles", phones));
			nvps.add(new BasicNameValuePair("params", params));

			result = NeteaseSms.newPost(st, nvps);
		}

		return result;
	}

	public int saveSmsCode(SmsCodeValidate code) {
		return smsCodeMapper.saveSmsCode(code);
	}

	public int updateSmsCode(SmsCodeValidate code) {
		return smsCodeMapper.updateSmsCode(code);
	}

	public SmsCodeValidate getSmsCode(SmsCodeValidate code) {
		return smsCodeMapper.getSmsCode(code);
	}

	public SmsCodeValidate getSmsData(SmsCodeValidate code) {
		return smsCodeMapper.getSmsData(code);
	}

	public SmsCodeValidate getSmsTime(SmsCodeValidate sv) {
		return smsCodeMapper.getSmsTime(sv);
	}

	public void intiSmsData(SmsCodeValidate sv) {
		smsCodeMapper.intiSmsData(sv);
	}

	public SmsCodeValidate getSmsIsExpire(SmsCodeValidate code) {
		return smsCodeMapper.getSmsIsExpire(code);
	}

	@Override
	public int upudateIsSue(SmsCodeValidate code) {
		return smsCodeMapper.upudateIsSue(code);
	}

	public String userIsNull(SmsCodeValidate sms) {
		UserLogin ul = new UserLogin();
		ul.setPhone(sms.getPhone());
		UserLogin login = userService.getUserLoginByPhone(ul);
		if (StringUtils.equals(sms.getTypes(), "login") || StringUtils.equals(sms.getTypes(), "password")) {
			if (login == null) {
				return "no_exists";
			}
		}
		if (StringUtils.equals(sms.getTypes(), "register")) {
			if (login != null) {
				return "is_exists";
			}
		}
		return "success";
	}

	@Override
	public Map<String, Object> sendSmsCode(SmsCodeValidate sms) {
		Map<String, Object> resMap = new HashMap<String, Object>();
		String msg = "", code = "";
		try {
			String message = userIsNull(sms);
			if ("no_exists".equals(message)) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "no_exists", "该手机号码尚未注册!"));
				return resMap;
			} else if ("is_exists".equals(message)) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "is_exists", "该手机号码已注册!"));
				return resMap;
			}
			SmsCodeValidate validate = smsCodeMapper.getSmsData(sms);
			if (validate == null) {
				sms.setExpireTime("600");
				sms.setCode(CustomUtil.buildRandom(6) + "");
				sms.setSendNum(0);
				msg = saveSendDB(sms, true);
				return resMap;
			}
			Date createTime = DateUtil.fomatDateTime(validate.getCreateTime(), "yyyy-MM-dd HH:mm:ss");

			int days = DateUtil.daysOfTwo(createTime, new Date());
			if (days != 0) {
				validate.setSendNum(0);
				smsCodeMapper.intiSmsData(validate);
				sms.setExpireTime("600");
				sms.setCode(CustomUtil.buildRandom(6) + "");
				msg = saveSendDB(sms, false);
				return resMap;
			}
			if (validate.getSendNum() > 10) {
				msg = "max";
				return resMap;
			}
			if (validate.getSendNum() < 3) {
				sms.setExpireTime("600");
				code = CustomUtil.buildRandom(6) + "";
				sms.setCode(code);
				msg = saveSendDB(sms, false);
				return resMap;
			}
			long now = System.currentTimeMillis();
			long dates = Long.valueOf(DateUtil.dateToStamp(validate.getCreateTime())).longValue();
			if (validate.getSendNum() >= 3 && ((now / 1000) - (dates / 1000)) > 900) {
				sms.setExpireTime("600");
				code = CustomUtil.buildRandom(6) + "";
				sms.setCode(code);
				msg = saveSendDB(sms, false);
				return resMap;
			}
			msg = "often";
			return resMap;
		} catch (Exception e) {
			msg = "exception";
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return resMap;
		} finally {
			if (StringUtils.equals(msg, "success")) {
				/* resMap.put("code", sms.getCode()); */
				resMap.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, msg, "发送成功"));

			} else if (StringUtils.equals(msg, "max")) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, msg, "获取验证码已经达到上线请在次日后再试"));
			} else if (StringUtils.equals(msg, "exception")) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, msg, "系统异常"));
			} else if (StringUtils.equals(msg, "often")) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, msg, "请求次数过于频繁,请15分钟后重发"));
			} else if (StringUtils.equals(msg, "error1")) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, msg, "请求次数过于频繁"));
			} else {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, msg, "发送失败"));
			}
		}
	}

	private String saveSendDB(final SmsCodeValidate sms, Boolean o) {
		String msg = "success";
		try {
			int i = 0;
			if (o) {
				sms.setIsUse("00");
				i = smsCodeMapper.saveSmsCode(sms);
			} else {
				sms.setIsUse("00");
				i = smsCodeMapper.updateSmsCode(sms);
			}
			if (i >= 1) {
				msg = sendCode(sms.getTypes(), sms.getCode(), sms.getPhone());
			}
			if ("success".equals(msg)) {
				return "success";
			} else if ("error1".equals(msg)) {
				return "error1";
			} else {
				return "error";
			}
		} catch (Exception e) {
			e.printStackTrace();
			return "error";
		} finally {
			if (!"success".equals(msg)) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}
		}
	}

	@Override
	public String getValidateCode(String phone, String code, String type) {
		String msg = "ok";
		try {
			SmsCodeValidate sms = new SmsCodeValidate();
			sms.setPhone(phone);
			sms.setCode(code);
			sms.setTypes(type);
			SmsCodeValidate validate = smsCodeMapper.getSmsCode(sms);
			if (validate == null) {
				msg = "not_exists";
			} else {
				if ("01".equals(validate.getIsUse())) {
					msg = "expire";
				} else {
					String time = validate.getExpireTime();
					long lose = Long.parseLong(time);

					Long newTime = System.currentTimeMillis();
					if (lose < (newTime / 1000)) {
						msg = "expire";
					}
				}
			}
			if ("ok".equals(msg)) {
				SmsCodeValidate date = new SmsCodeValidate();
				date.setCode(code);
				date.setPhone(phone);
				date.setTypes(type);
				date.setIsUse("01");
				int num = smsCodeMapper.upudateIsSue(validate);
				if (num == 0) {
					msg = "error";
				}
			}
		} catch (Exception e) {
			msg = "error";
		}
		return msg;
	}

}
